!pip install opencv-python
!pip install keras
!pip install opencv-python-headless
Requirement already satisfied: opencv-python in c:\users\suned\anaconda3\lib\site-packages (4.8.0.76) Requirement already satisfied: numpy>=1.21.2 in c:\users\suned\anaconda3\lib\site-packages (from opencv-python) (1.23.5) Requirement already satisfied: keras in c:\users\suned\anaconda3\lib\site-packages (2.12.0) Requirement already satisfied: opencv-python-headless in c:\users\suned\anaconda3\lib\site-packages (4.8.0.76) Requirement already satisfied: numpy>=1.21.2 in c:\users\suned\anaconda3\lib\site-packages (from opencv-python-headless) (1.23.5)
import numpy as np
import matplotlib.image as mpimg
import matplotlib.pyplot as plt
import cv2
import os
import json
from IPython.display import display, clear_output, HTML
from tkinter import filedialog
from tkinter import Tk
import unittest
import subprocess
from unittest.mock import patch
import pytest
This project serves as a software-based simulation designed to emulate real-world technology applications. Consider the sample thermal map and thermal video drone footage provided below as a representative example of a geographical area over which a drone would be directed to conduct a flight in an actual operational context, as captured through an infrared imaging system:
# Displaying the image using Matplotlib:
img_path = './Map smaller size.png'
img = mpimg.imread(img_path)
plt.imshow(img)
plt.axis('off')
plt.show()
# Displaying the video using HTML5 <video> tag:
video_path = 'test video.mp4'
video_html = f'<video width="640" height="360" controls><source src="test video.mp4" type="video/mp4">Your browser does not support the video tag.</video>'
display(HTML(video_html))
Assumption 1: In a practical scenario, the drone is presumed to maintain a consistent altitude of 15 meters above the ground level.
Assumption 2: Given that this project involves a simulation and lacks access to an actual infrared camera, it is posited that the camera is assumed to have a horizontal field of view of 100 degrees, and a vertical field of view of 90 degrees. The footage will be taken at an aspect ratio of 4:3, since it it generally the most common for general-use thermal cameras.
Assumption 3: In a practical scenario, the drone will be programmed to consistently navigate over a rectangular region with an area of 12500 square meters. This corresponds to dimensions of 125 meters in length (vertical) and 100 meters in width (horizontal). The navigation will be facilitated through the utilization of established flight planning software, such as DJI GO or DJI Fly. It is important to note that the integration and operation of this software falls outside the scope of this project, as the focus here is solely on simulation.
Assumption 4: The drone is presumed to consistently follow the up and down flight path depicted in the subsequent image:
img_path = './flight path.png'
img = mpimg.imread(img_path)
plt.imshow(img)
plt.axis('off')
plt.show()
Assumption 5: The operational flight area, referred to as the "map," will be subdivided into smaller, distinct sections, forming a grid. This grid is consistently structured to comprise four rows and three columns, as depicted in the accompanying illustration.
The drone is programmed to initiate its flight path from Block 1. Utilizing its thermal/infrared camera, the drone will commence recording as it navigates through the predetermined path: starting from Block 1, proceeding to Block 2, then to Block 3, and continuing sequentially until it reaches Block 12. At each block, a single frame from the infrared video footage will be captured for further analysis. The frame will be extracted once the drone is in the middle of each block, as depicted by the dots in the image above.
Subsequent to the capture of each frame, the corresponding block will be meticulously scanned for the presence of human individuals. In the event that a human is detected within a block, the pixel coordinates of this individual will be identified and reported. Notably, these coordinates are provided in relation to the entire map, rather than the isolated, cropped section of the current block. In a real-world application, these pixel coordinates are intended to correspond with actual GPS coordinates.
Furthermore, each block within the grid is designed with specific dimensions: A horizontal length of 33,33 meters, a vertical length of 31,25 meters, and a total area of 1041,56 square meters.
Note: The maps used for simulation purposes are not up to scale.
Assumption 6: It has been roughly calculated that a drone flying 15 meters above ground, at the speed of 3 meters per second, it will take, on average, approximately 126.39 seconds (2.11 minutes) to record footage of the entire area, given that the entire flight path has been calculated to be 379.16 meters long.
# Run the Human_Detection_Script.py script using subprocess
result = subprocess.run(['python', 'Human_Detection_Script.py'], capture_output=True, text=True)
# Check if the script ran successfully by examining the return code
if result.returncode == 0:
print("Test passed: Script ran successfully.")
else:
print(f"Test failed: Script returned error code {result.returncode}.")
Test passed: Script ran successfully.
%run Human_Detection_Script.py
Loaded video file 'test video.mp4' with size: 26.77 MB successfully. Video file 'test video.mp4' opened successfully. Original Duration: 126.38 seconds Desired Duration: 126.39 seconds Original FPS: 24 New FPS: 24.00 Processed video saved as output_video.mp4 with new duration of 126.39 seconds Block 1: 5.21 seconds Block 2: 15.62 seconds Block 3: 26.04 seconds Block 4: 37.15 seconds Block 5: 47.57 seconds Block 6: 57.98 seconds Block 7: 68.4 seconds Block 8: 79.51 seconds Block 9: 89.93 seconds Block 10: 100.34 seconds Block 11: 110.76 seconds Block 12: 121.87 seconds Function 'grab_frames' defined successfully! Function 'crop_to_aspect_ratio' defined successfully. Calculated Aspect Ratio: 1.07 Frames grabbed successfully!
Bounding boxes for Block 1: [(36, 362, 118, 418), (960, 172, 1058, 226)]
Bounding boxes for Block 2: [(146, 714, 220, 828), (708, 4, 747, 27)]
Bounding boxes for Block 3: [(482, 492, 576, 606), (456, 526, 478, 548)]
Bounding boxes for Block 4: [(850, 508, 984, 624)]
Bounding boxes for Block 5: [(880, 746, 992, 828), (200, 26, 380, 100)]
Bounding boxes for Block 6: [(996, 970, 1098, 1076), (410, 160, 456, 188)]
Bounding boxes for Block 7: [(684, 276, 788, 334)]
Bounding boxes for Block 8: [(26, 786, 88, 836), (800, 670, 836, 734), (316, 296, 384, 354)]
Bounding boxes for Block 9: [(712, 682, 834, 726)]
Bounding boxes for Block 10: [(306, 882, 342, 914), (876, 552, 914, 612), (208, 154, 322, 206)]
Bounding boxes for Block 11: [(172, 378, 228, 466)]
Bounding boxes for Block 12: [(278, 716, 352, 806), (772, 0, 870, 28)] Total number of humans: 22 Map dimensions: Width = 3453 pixels, Height = 4320 pixels